package com.eshin;

import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import com.eshin.mdcdecorator.MDCSpringMvcHandlerInterceptor;
import com.eshin.mdcdecorator.MDCTaskDecorator;

/**
 * 日志组件自动装配
 *
 * @author ESHIN
 */
//即使用jdk默认代理模式，AspectJ代理模式是CGLIB代理模式
//如果目标对象实现了接口，默认情况下会采用JDK的动态代理实现AOP
//如果目标对象实现了接口，可以强制使用CGLIB实现AOP (此例子我们就是强制使用cglib实现aop)
//如果目标对象没有实现了接口，必须采用CGLIB库，spring会自动在JDK动态代理和CGLIB之间转换

@Configuration
@ConditionalOnProperty(
        value = "come.eshin.logging.enabled",
        havingValue = "true",
        matchIfMissing = true)
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
public class LoggingAutoConfiguration {
    
    @Value("${come.eshin.executor.max-pool-size:16}")
    int maxPoolSize;
    
    /**
     * 自定义线程池
     * <p>
     * 用于线程切换时的MDC延续
     */
    @Bean
    public TaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(maxPoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setTaskDecorator(new MDCTaskDecorator());
        executor.setThreadNamePrefix("MdcTransRun-");
        executor.initialize();
        return executor;
    }
    
    @Bean
    public DefaultKeywords defaultKeywords() {
        return new DefaultKeywords();
    }
    
    @Bean
    public String configDefaultKeywords(DefaultKeywords defaultKeywords) {
    	MDC.setContextMap(defaultKeywords.getDefaultKeyValues());
    	return "successfully";
    }
    
    @Bean
    public MDCSpringMvcHandlerInterceptor mdcSpringMvcHandlerInterceptor() {
        return new MDCSpringMvcHandlerInterceptor();
    }
    
    /**
     * Filter与Interceptor装配
     */
    @Configuration
    class LoggingWebConfiguration implements WebMvcConfigurer{
        
        @Autowired
        MDCSpringMvcHandlerInterceptor mdcSpringMvcHandlerInterceptor;
        
        
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
        	registry.addInterceptor(mdcSpringMvcHandlerInterceptor);
//        	WebMvcConfigurer.super.addInterceptors(registry);
        }
        /*@Bean
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(mdcSpringMvcHandlerInterceptor);
        }*/
    }
}
